package com.mezz.bones.framework.web.advice;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.StopMatchException;
import com.mezz.bones.framework.base.domain.enums.ResponseCode;
import com.mezz.bones.framework.base.domain.response.Result;
import com.mezz.bones.framework.base.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.sql.SQLException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    public Result<?> maxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        return Result.error("上传文件过大");
    }

    @ExceptionHandler(value = SQLException.class)
    public Result<?> sqlException(SQLException e) {

        log.error("SQL异常={}", e.getMessage(),e);
        return Result.sysErrorWithCode(ResponseCode.SQL_ERROR);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> exceptionHandler(MethodArgumentNotValidException ex) {
        //获取Servlet容器
        BindingResult bindingResult = ex.getBindingResult();

        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            return Result.error(fieldError.getDefaultMessage());
        }

        return Result.error(ResponseCode.PARAM_ERROR);
    }

    @ExceptionHandler(org.springframework.validation.BindException.class)
    public Result<?> exceptionBindHandler(org.springframework.validation.BindException ex) {
        //获取Servlet容器
        BindingResult bindingResult = ex.getBindingResult();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            return Result.error(fieldError.getDefaultMessage());
        }

        return Result.error(ResponseCode.PARAM_ERROR);
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<?> httpNotReadableHandler(HttpMessageNotReadableException ex) {
        String message = "请求参数异常，请检查入参格式";
        return Result.error(message);
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result<String> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex) {
        return Result.error("HTTP method not supported");
    }

    @ExceptionHandler(BaseException.class)
    public Result<?> baseExceptionHandler(BaseException ex) {
        log.error("baseExceptionHandler error",ex);

        //后续有做国际化 这边单独处理返回的message
        return Result.error(ex.getCode(), ex.getMsg());
    }

    @ExceptionHandler(Exception.class)
    public Result<?> exceptionHandler(Exception ex) {

        log.error("exceptionHandler error",ex);
        return Result.error( ex.getMessage());
    }

    @ExceptionHandler(Throwable.class)
    public Result<?> throwableHandler(Throwable ex) {
        log.error("throwableHandler error",ex);
        return Result.error( ex.getMessage());
    }

    @ExceptionHandler(NotLoginException.class)
    public Result<?> handleNotLoginException(NotLoginException e) {
        return Result.error(ResponseCode.USER_NOT_LOGIN);
    }

    @ExceptionHandler(StopMatchException.class)
    public Result<?> handleStopMatchException(StopMatchException e) {
        return Result.error(ResponseCode.USER_NOT_PERMISSION);
    }
}
